#include "WOP_Entry.h"
#include <iostream>
#include "Command_Agent.h"
#include <cassert>
#include "DIVA_Manager.h"
//#include "include/MappingDialogProxy.h"
//#include "MappingDialog/Visualizer/MappingResult.h"
#include "Utility.h"


using namespace std;
extern xMappingTree* mTree;
void WOP_Entry::init(string s, WOP_Entry *parent){
	assert(s.size()>0);
	//VM = NULL;
	_name = s;
	_parent = parent;
	_from = NULL ;
	_descentfrom = NULL ;
	_top = false;
	if(_parent == NULL)
		_top = true;
	_updated = false;
	_inscope = true ;
	_value = "@null@" ; // this value should not be changed. It is used in wop_ref_entry.cpp to handle first time update
	_addr = "" ;
	//_classid = "" ;
	// update();  2008/9/29 we do not want to update everytime because of the arithmetic nodes.
}
void WOP_Entry::setDescentFrom(WOP_Entry * from)  {
		if (from != NULL) {                                    // this wop is unfolded from other reference VM
       	                                                                           // we copy its _descentfrom
			if (from->isTop()) 
		 			_descentfrom = from ;
		    else  
					_descentfrom = from->getDescentFrom();
			
		}
}
string WOP_Entry::getActualPath(){

	assert(false); // ALERT! NO LONG USED
	string path = _name;
	if(this->_parent == NULL)
		return path;
	/*
	沒有_parent的人，必定是由user手動visual的
	而_parent必為Heap_Entry。
	只是為了防止互相include的問題，逼他成為WOP_Entry
	*/
	//assert(_parent->isUpdated());
	//string _parent->
	//assert(().size()>0);
	
	//path = _parent->getActualPath(_name);//所以，我要詢問親生父親--到底我的本名叫什麼 Q_Q
	//cout << "current parent: " << _parent << " current path: " << _parent->getActualPath() << endl;

	path = _parent->getActualPath();
	assert(_parent->getActualPath().size() > 0);
	if (_name.find("[") == _name.npos)
		path += ".";
	path.append(_name);

	return path;

}



string WOP_Entry::getName(){
	int index ;
	index = _name.find_last_of(".");
	return _name.substr(index+1);
}

string WOP_Entry::getLongName() {
	return _name ;
}
string * WOP_Entry::getNamePtr() {
	return &(_name) ;
}
WOP_Entry* WOP_Entry::getParent(){
	return _parent;
}
bool WOP_Entry::isTop(){
	return _top;
}
bool WOP_Entry::isUpdated(){
	return _updated;
}
void WOP_Entry::setUpdated(bool t){
	_updated = t;
}

WOP_Entry* WOP_Entry::findMatchedWOP(string vartype, string shortname) {
	if (_vartype != vartype ) return NULL ;
	string str  = getName();
	if (str.find("[") == string::npos) { // this is a name without [][]. It is not an array element
		if (getName() == shortname) // this is the case where the name and type are both matced
			return this ;
		else if (this->isTop())    //  this is the case where type is matched but name is not matched
			return this ;          //  we check if it is a top variable. For example, in ref.java
		                           //  there are two pointers p,q of the same type, when p is visualized first and applyall
		                           //  q should have the same mds as p
		else return NULL ;
	}

	// this is the case that the name is of the form xxx[5][6] to compared with yyy[5][6]
	// we only compare if "[5][6]" is equal to "[5][6]"
	// xxx and yyy will be discarded

	int index1 = str.find_first_of("[");
	int index2 = str.find_last_of("]");
	if (index1 != str.npos && index2 != str.npos) { // we have an array type ;
		// get rid of the array dimension part
		str = str.substr(index1, index2-index1+1);
	} else {
	    assert(false);
	}


	string str2= shortname ;
	index1 = str2.find_first_of("[");
	index2 = str2.find_last_of("]");
	if (index1 != str2.npos && index2 != str2.npos) { // we have an array type ;
		// get rid of the array dimension part
		str2 = str2.substr(index1, index2-index1+1) ;
	} else {
	    assert(false);
	}
	if (str == str2) return this ;
	else return NULL ;
	

}

void WOP_Entry::unfold(){
	assert(false);	
	//empty，only Ref_Entry//ArrayRef_Entry should overwrite and implement it
	//這邊不應該在Ref_Entry以外被呼叫到
}

void WOP_Entry::check_scope() {

	Command_Agent* ca = Command_Agent::getInstance();
	_inscope = ca->check_scope(_name);//向CommandAgent要求更新數值
}

std::pair< WOP_Entry*, xMappingTree* > WOP_Entry::setupVM()
{
//	DIVA_Manager::getInstance()->release();
//	MappingDialogProxy::getInstance()->showDialog(this);
//	DIVA_Manager::getInstance()->lock();

	// 使用者拉完 mapping 之後會將結果儲存在 MappingResult class 裡
	//return MappingResult::getInstance()->getMappingTree();
	return createMappingFromUI( this );
}


/*
void WOP_Entry::update(){	


	assert(false); // this method should be overriden and sho
	if(_updated)//如果已經更新，那就跳過
		return;		
	Command_Agent* ca = Command_Agent::getInstance();
	_value = ca->getValue(getActualPath());//向CommandAgent要求更新數值
	//突然想到可怕的問題...要是連型態都換了怎麼辦？
	_updated = true;

}
*/
